//LICENSE:  GPLv2

#include "../../meta_functions.h"
#include "../../structure.h"
#include "../../error.h"
#include "../../gui_io.h"
#include <stdio.h>
#include <stdlib.h>


int foldercmp(const char *a, const char *b)
{ //return 0 for same, 1 for not same
  int c;
  for (c=0; a[c] && b[c]; ++c)
    if (a[c] != b[c])
      return 1;
  const char *p;
  if (a[c])
    p = &(a[c]);
  else if (b[c])
    p = &(b[c]);
  else
    return 0;
  for (c=0; p[c] == '/'; ++c)
    ;
  if (p[c])
    return 1;
  return 0;
}

void __dynamic_srch(const char *fileName, void *a, void *b)
{
  int lyric = *((int *)b);
  const char *term = (const char *)a;

  struct elog_xml_doc *doc = elog_xml_open(fileName, 0);
  if (!doc)
    return;
  unsigned int len;
  unsigned char *t = elog_io_readRestofFile(doc->handle, &len);
  elog_io_close(doc->handle);
  
  if (!(doc->file_info->encType))  elog_sp_cat(&(doc->file_info->encType), "AES", NULL); //if there was no enc tag, make one as AES just in case

  if (elog_journ_current()->settings->encryption[0] == 'A'
      || doc->file_info->encType[0] == 'A')
    decryptText(t, len); //decrypt if necessary
    

  char *text = elog_sp_toChar(t, len);
  

  if (lyric)
    lyric = elog_srch_lyrical(text);
  else
    lyric = 1;

  int *results = elog_srch_listResults(text, term);
  if (results[0] != -1 && lyric)
      lst_al_add_item(doc->subject, 1, fileName);
  
  if (results)
    free(results);
  elog_xml_doc_free(doc);
}

int lst_act_open_folder(char *folder)
{
  char *fold;
  elog_sp_cat(&fold, folder, NULL);
  char *last_slash = strrchr(fold, '/');
  if (last_slash[1] == '\0')
    { //it has a ending slash
      last_slash[0] = '/';
      last_slash = strrchr(fold, '/');
    }
  last_slash[0] = '\0';

  lst_al_clear();
  lst_al_add_item("..", 0, fold);

  printf("Folder:%s\n", fold);
  
  free(fold);

  free(_plgn_folder_cur);
  elog_sp_cat(&_plgn_folder_cur, folder, "/", NULL);
  /*First open subfolders:*/ 
  
 

  /********************************/
  char *datFile;
  elog_sp_cat(&datFile, folder, "/folder.xml", NULL);
  struct elog_io_file *f = elog_io_initialize(datFile, ELOG_IO_READ);
  free(datFile);
  if (f)
    {
      unsigned int len;
      unsigned char *tmp = elog_io_readRestofFile(f, &len);
      char *xml = elog_sp_toChar(tmp, len);
      elog_io_close(f);
      int type;
      elog_xml_scanf(xml, "<folder>.<type>.%i", &type);
      switch (type)
	{
	case PLGN_TYPE_DYNAMIC:
	  {
	    int lyric = 0;
	    int code = 0;
	    char *term = NULL;
	    elog_xml_scanf(xml, "<folder>.<term>.%s", &term);
	    elog_xml_scanf(xml, "<folder>.<lyric>.%i", &lyric);
	    elog_xml_scanf(xml, "<folder>.<code>.%i", &code);
	    
	    if (lyric || code)
	      lyric = 1;
	    elog_func_apply_recursively(elog_journ_current()->settings->path, __dynamic_srch, NULL, term, &lyric);

	    free(term);

	    break;
	  }
	case PLGN_TYPE_STATIC:
	  {
	    char *files;
	    elog_xml_scanf(xml, "<folder>.<files>.%s", &files);

	    char **items = elog_sp_breakToArr(files, '\n');
	    if (!items)
	      {
		elog_err_print("Error: Broken static directory\n");
		free(files); free(xml);
		return 1;
	      }
	    int c;
	    for (c=0; items[c]; ++c)
	      { //Name:fileName\n
		char **subTexts = elog_sp_breakToArr(items[c], ':');
		char *path;
		elog_sp_cat(&path, elog_journ_current()->settings->path, "/", subTexts[1], NULL);
		if (subTexts[0][0] == '\0')
		  {//blank name
		    struct elog_xml_doc *doc = elog_xml_open(path, 0);
		    lst_al_add_item(doc->subject, 1, path);
		    //using the document subject
		    elog_io_close(doc->handle);
		    elog_xml_doc_free(doc);
		  }
		else
		  lst_al_add_item(subTexts[0], 1, path);
		free(path);

		elog_sp_ArrFree(subTexts);
	      }
	    elog_sp_ArrFree(items);
	    free(files);
	    break;
	  }
	}
      
      
      free(xml);
    }
  else
    elog_wrn_print("lst_plugin:Can't find folder.xml\n");

  if (_plgn_folder_cur)
    free(_plgn_folder_cur);
  elog_sp_cat(&_plgn_folder_cur, folder, NULL);

  return 0;
}

int lst_act_open_file(char *file)
{
  if (elog_gui_io_open(file, NULL))
    return 0;
  return 1;
}

void __addEntry(const char *fileName, void *a, void *b)
{
  int *p = (int *)a;
  int l = *p;
  const char *file = &(fileName[l]);
  int len = strlen(file);
  if (strcmp(&(file[len-4]), ".dry") == 0)
    {
      struct elog_xml_doc *doc = elog_xml_open(fileName, 0);
      if (doc)
	{
	  lst_al_add_item(doc->subject, 1, fileName);
	  elog_io_close(doc->handle);
	  elog_xml_doc_free(doc);
	}
    }
}
int lst_act_root()
{
  lst_al_clear();
  lst_al_add_item("All Entries", 0, "ALL ENTRIES");

  lst_al_add_item("Trash", 0, "TRASH");
  
  free(_plgn_folder_cur);
  elog_sp_cat(&_plgn_folder_cur, _plgn_folder_root, NULL);

  printf("Root is:%s\n", _plgn_folder_cur);
  char **list = elog_io_dirContents(_plgn_folder_cur);
  int c;
  for (c=0; list[c]; ++c)
    {
      if (strcmp(list[c], "All Entries") != 0 &&
	  strcmp(list[c], "Trash"))
	{
	  char *path;
	  elog_sp_cat(&path, _plgn_folder_cur, list[c], NULL);
	  if (elog_io_stat(path) == ELOG_IO_STAT_DIR)
	    {
	      lst_al_add_item(list[c], 0, path);
	    }
	  free(path);
	}
    }
  return 0;
}


void lst_act_refresh()
{
  if (foldercmp(_plgn_folder_cur, _plgn_folder_root) == 0)
    {
      lst_al_clear();
      lst_act_root();
    }
  else
    {
      char *name;
      elog_sp_cat(&name, _plgn_folder_cur, NULL);
      lst_act_open_folder(name);
      free(name);
    }
}


int lst_act_open_item(char *item)
{
  if (strcmp(item, "TRASH") == 0)
    {
      
      return 0;
    }
  if (strcmp(item, "ALL ENTRIES") == 0)
    {
      lst_al_clear();
      lst_al_add_item("..", 0, _plgn_folder_cur);

      int l = strlen(elog_journ_current()->settings->path);
      elog_func_apply_recursively(elog_journ_current()->settings->path, __addEntry, NULL, &(l), NULL);
      return 0;
    }
  if (foldercmp(item, _plgn_folder_root) == 0)
    {
      lst_al_clear();
      lst_act_root();
      return 0;
    }

  printf("Opening:%s\n", item); 
  int stat = elog_io_stat(item);

  switch (stat)
    {
    case ELOG_IO_STAT_DIR:
      {
	lst_act_open_folder(item);
	break;
      }
    default: //otherwise, hope it works like a file!
      {
	lst_act_open_file(item);
	break;
      }
    }
  return 0;
}
int lst_act_initialize(char *dir)
{
  if (_plgn_folder_cur)
    free(_plgn_folder_cur);
  if (_plgn_path)
    free(_plgn_path);
  //initializing current folder setting:
  elog_sp_cat(&_plgn_folder_cur, dir, "/cat/", NULL);
  elog_sp_cat(&_plgn_path, _plgn_folder_cur, NULL);


  struct stat buf;
  if (stat(_plgn_path, &buf) == -1)
    elog_io_mkdir(_plgn_path);
  

  if (!(_plgn_img_page))
    {

      char *path;
      elog_sp_cat(&path, PLGN_DATADIR, "/ejourn/img/add2.png", NULL);
      struct elog_io_file *f = elog_io_initialize(path, ELOG_IO_READ);
      
      if (f)
	{
	  _plgn_img_page = elog_io_readRestofFile(f, &_plgn_img_len_page);
	  elog_io_close(f);
	}
      else
	{
	  elog_err_print_console("Failed to open page icon for lst_plugin:");
	  elog_err_print_console(path);
	  elog_err_print_console("\n");
	}
      free(path);
    }

  if (!(_plgn_img_folder))
    {
      char *path;
      elog_sp_cat(&path, PLGN_DATADIR, "/ejourn/img/folder_32.png", NULL);
      struct elog_io_file *f = elog_io_initialize(path, ELOG_IO_READ);
      
      if (f)
	{
	  _plgn_img_folder = elog_io_readRestofFile(f, &_plgn_img_len_folder);
	  elog_io_close(f);
	}
      else
	{
	  elog_err_print_console("Failed to open folder icon for lst_plugin:");
	  elog_err_print_console(path);
	  elog_err_print_console("\n");
	}
      free(path);
    }
  
  if (_plgn_folder_root)
    free(_plgn_folder_root);
  elog_sp_cat(&_plgn_folder_root, _plgn_folder_cur, NULL);
  
  lst_act_root();

  char *all;
  elog_sp_cat(&all, _plgn_path, "All Entries", NULL);
  if (stat(all, &buf) == -1)
    elog_io_mkdir(all);
  free(all);  

  return 0;
}

